import { ref, reactive, onUnmounted, onMounted, nextTick } from "vue";
import {
  Leafer,
  App,
  Text,
  Image,
  ImageEvent,
  ZoomEvent,
  ResizeEvent,
  ChildEvent,
  LeaferEvent,
  PropertyEvent,
  Group,
} from "leafer-ui";
import { PenTool } from "../tools/PenTool";
import { TextTool } from "../tools/TextTool";

import type { ITool, IToolConfig, IToolReturn } from "../types";
import { createBaseTool } from "../core/BaseTool";
import "@leafer-in/editor";
import "@leafer-in/text-editor";
import "@leafer-in/view";
import "@leafer-in/animate";
import "@leafer-in/viewport";

import { ShapeTool } from "../tools/ShapeTool";
import { EaserTool } from "../tools/EaserTool";
import { isFunction } from "@/utils/is";
import { useDebounceFn } from "@vueuse/core";
import useHistoryUtil from "./useHistoryUtil";

const zoomConfig = {
  step: 0.2,
  min: 0.2,
  max: 5,
  padding: 10,
};
export const useDrawing = (containerId: string) => {
  // 初始化Leafer
  let app: App;
  let box: Group;
  // 响应式配置
  const config = reactive<IToolConfig>({
    pen: { color: "#C40833", strokeWidth: 6, opcity: 1 },
    eraser: { size: 20 },
    text: { fontSize: 20 },
    shape: {
      fill: "transparent",
      stroke: "#FF4C26",
      strokeWidth: 4,
      type: "rect",
    },
  });
  const activeTool = ref("");
  const loading = ref(false);
  let bgImage: Image | null = null;
  let fitScale = 1;
  const scale = ref(1);
  const historyUtil = useHistoryUtil((v: any) => {
    box.set({
      children: v?.children ?? [],
    });
  });

  // 工具Map
  let toolMap: Record<string, any> = {
    pen: PenTool,
    text: TextTool,
    shape: ShapeTool,
    easer: EaserTool,
  };
  let toolManager: any;
  // 切换工具
  const setActiveTool = (toolName: string) => {
    if (activeTool.value === toolName) return;
    toolManager?.unregisterEvents?.();
    activeTool.value = toolName;
    const tool = toolMap[toolName];
    if (!tool) return;
    toolManager = createBaseTool(app, tool({ app, config, historyUtil, box }));
    // if(isFunction(tool)){
    //   toolManager = createBaseTool(app, toolMap[toolName]({app, config,historyUtil}) );
    //   toolMap[toolName] = toolManager;
    // }else {
    //   toolManager = tool;
    // }
    toolManager.registerEvents();
  };
  const init = () => {
    app = new App({
      view: containerId,
      editor: {
        //是否启用框选功能
        boxSelect: false,
      },
      smooth: true,
      pointer: { touch: true },
      touch: { preventDefault: true },
    });
    app.on(ZoomEvent.ZOOM, function () {
      scale.value = +app.scale / fitScale;
    });
    //监听画布大小改变
    app.on(ResizeEvent.RESIZE, () => {
      hanResize();
    });
  };
  const initData = (dataStr: string) => {
    if (box) {
      app.tree.remove(box);
    }
    box = new Group({
      x: 0,
      y: 0,
      zIndex: 1,
    });
    app.tree.add(box);
    if (!!dataStr) {
      const data = JSON.parse(dataStr);
      box.set(data);
      historyUtil.init(data);
    } else {
      historyUtil.init(box.toJSON());
    }
    setActiveTool("");
  };
  const initImg = async (data: {
    url: string;
    penData: string | undefined | null;
  }) => {
    loading.value = true;
    return new Promise<void>((resolve, reject) => {
      if (bgImage) {
        app.tree.remove(bgImage);
        app.tree.remove(box);
      }
      bgImage = new Image({
        url: data.url,
        pixelRatio: 3,
        hittable: false,
        zIndex: 0,
      });
      app.tree.add(bgImage);
      bgImage.once(ImageEvent.LOADED, async (e: ImageEvent) => {
        await nextTick();
        app.tree.zoom("fit", zoomConfig.padding);
        scale.value = 1;
        fitScale = +(app.tree.scale ?? 1);
        app.data.fitScale = fitScale;
        app.tree.config.zoom = {
          min: zoomConfig.min * fitScale,
          max: zoomConfig.max * fitScale,
        };
        initData(data.penData);
        loading.value = false;
        resolve();
      });
    });
  };
  const hanResize = useDebounceFn(() => {
    if (!app.ready) return;
    if (!bgImage) return;
    app.tree.zoom(bgImage, zoomConfig.padding, !true, 0.2);
    scale.value = 1;
  }, 300);

  const hanRotate = (isLeft: boolean) => {
    app.rotateOf("center", isLeft ? -90 : 90);
  };
  const hanScale = (isAdd: boolean) => {
    const step = zoomConfig.step;
    let newScale = scale.value + (isAdd ? step : -step);
    if (newScale < zoomConfig.min) newScale = zoomConfig.min;
    if (newScale > zoomConfig.max) newScale = zoomConfig.max;
    scale.value = newScale;
    const target = newScale * fitScale;
    app.zoom(target, zoomConfig.padding, false, 0.2);
  };
  const hanClear = () => {
    box.clear();
    historyUtil.commit(box.toJSON());
  };
  onMounted(() => {
    init();
  });
  // 清理资源
  onUnmounted(() => {
    app.destroy();
  });

  return {
    activeTool,
    config,
    setActiveTool,
    initImg,
    historyUtil,
    hanRotate,
    hanScale,
    hanClear,
  };
};
